/*
Author: Quiksilver
Script Name: Soldier Tracker v1.0.2 士兵追踪器
Contact: camball@gmail.com ||  http://forums.bistudio.com/showthread.php?184108-Soldier-Tracker-(-Map-and-GPS-Icons-)
Created: 8/08/2014
Version: v1.0.1
Last modified: 14/10/2014 ArmA 1.30 by Quiksilver
Installation: Follow instructions posted in the below link
DESCRIPTION:
	A CPU-friendly Player Icons script for showing players and vehicles on the map interfaces.
	Developed for my in-development co-op mission, decided to package and release it by itself.
	This version contains the basics.
	Designed for realism. No fancy frills, bright colors or gimmicky features.
	Enjoy!
	
	Note: 
	Common medical variables for icon color.
	Replace the relevant line in QS_fnc_iconColor (~line 37) with the correct line below:
	
	BTC Revive: 		  if (_u getVariable ["BTC_need_revive",0] isEqualTo 1) exitWith {[1,1,1,1]};
	Farooq's Revive: 	  if (_u getVariable ["FAR_isUnconscious".0] isEqualTo 1) exitWith {[1,1,1,1]};
	AIS Wounding System:  if (_u getVariable ["unit_is_unconscious",false]) exitWith {[1,1,1,1]};
	...
	
k1升级优化 2021.11.20  添加新版 2.5.0 (released 24/02/2018 A3 1.80) 部分功能
通过缩放地图比例切换图标文本支持在地图GPS迫击炮电脑无人机控制器界面上显示友军单位图标。单机显示玩家小
队单位+全部可切换单位+友军无人机，多人显示友军玩家+可扮演的友好AI+友军无人机，游戏中添加设置选项
========================================================================================================*/

/////////////////////逃离专用/////////////////////

if (isDedicated) exitWith {};

if(isNil "QS_side_sw")then{QS_side_sw = false}; //true 用FAR保存的阵营来判断是否敌对
if(isNil "QS_MAPrequireGPSItem")then{QS_MAPrequireGPSItem = false}; //true 装配上GPS,uav终端才能在地图显示图标
if(isNil "QS_isUN_text")then{QS_isUN_text = false}; //true 倒下也显示图标文本
if(isNil "QS_TextSize_MAP")then{QS_TextSize_MAP = .05}; //MAP文本字体大小
if(isNil "QS_TextSize_GPS")then{QS_TextSize_GPS = .05}; //GPS文本字体大小
if(isNil "QS_showText_GPS")then{QS_showText_GPS = false}; //true GPS显示图标文本
if(isNil "QS_de_MapScale")then{QS_de_MapScale = false}; //true 一直显示图标文本
if(isNil "QS_crew_Mode")then{QS_crew_Mode = 0}; //[0,1,2,3] 乘员文本显示方式

QS_fnc_isIncapacitated = {
	(_this getVariable ["FAR_isUnconscious",0] isEqualTo 1 || {_this getVariable ["BTC_need_revive",0] isEqualTo 1} || {_this getVariable ["unit_is_unconscious",false]} || {_this getVariable ["tcb_ais_agony",false]} || {_this getVariable ["ACE_isUnconscious",false]} || {lifeState _this isEqualTo 'INCAPACITATED'})
}; //检查单位是否倒下，支持的医疗系统:FAR,BTC,AIS,AWS,ACE,BIS

QS_fnc_iconColor = {
	params ["_u",["_ms",0]];
	private _a = .7;
	if (group _u == group player) then {_a = .9};
	if (_ms > .80) then {_a = 0}; //0值隐藏图标
	if (_u call QS_fnc_isIncapacitated) exitWith {[1,.41,0,_a]}; //单位倒下时图标变成橙色
	if (side _u == east) exitWith {[.5,0,0,_a]};
	if (side _u == west) exitWith {[0,.3,.6,_a]};
	if (side _u == independent) exitWith {[0,.5,0,_a]};
	if (side _u == civilian) exitWith {[.4,0,.5,_a]};
	[.7,.6,0,_a]
};

QS_fnc_iconType = {
	private ["_v","_i"];
	_v = _this select 0;
	_i = _v getVariable ["icontype",""];
	if (_i == "") then {
		_i = getText (configFile >> "CfgVehicles" >> typeOf _v >> "icon");
		_v setVariable ["icontype",_i];
	};
	_i;
};

QS_fnc_iconSize = {
	private _v = _this select 0;
	if (_v isKindOf "Man") exitWith {22};
	if (_v isKindOf "LandVehicle") exitWith {26}; //28
	if (_v isKindOf "Air") exitWith {24}; //28
	if (_v isKindOf "StaticWeapon") then {22};
	if (_v isKindOf "Ship") exitWith {24}; //26
};

QS_fnc_iconText = {
	params ['_v',['_ms',1]];
	private _t = "";
	private _n = 0;
	private _vt = _v getVariable ["vt",""];
	if (_vt == "") then {
		_vt = getText (configFile >> "CfgVehicles" >> typeOf _v >> "displayName");
		_v setVariable ["vt",_vt];
	};
	private _vn = if(isMultiplayer && {!isPlayer (crew _v select 0)})then[{"[AI]"},{name (crew _v select 0)}];
	private _isAdmin = serverCommandAvailable "#kick";
	if (_v distance2D player < 3500 || {_isAdmin}) then [{
		_t = if(QS_de_MapScale)then[{format ['%1 [%2]',_vn,_vt]},{if(_ms < .60 || {_isAdmin})then[{if(_ms > .05 || {_isAdmin})then[{format ['%1 [%2]',_vn,_vt]},{if(_ms < .006)then[{format ['%1 [%2]',_vn,_vt]},{''}]}]},{''}]}];
	},{
		_t = if(QS_de_MapScale)then[{format ['%1',_vn]},{if(_ms < .60)then[{if(_ms > .05)then[{format ['%1',_vn]},{if(_ms < .006)then[{format ['%1',_vn]},{''}]}]},{''}]}];
	}];
	if (_v isKindOf 'LandVehicle' || {_v isKindOf 'Air'} || {_v isKindOf 'Ship'}) then {
		_n = ({alive _x} count crew _v) - 1;
		if (_n > 0) then [{
			if (QS_crew_Mode == 2 || {QS_crew_Mode == 0 && {(_ms <= .05 && {_ms > .025}) || {_ms < .006}}}) then [{
				_t = '';
				private _crewIndex = 0;
				private _na = '';
				_crewCount = ({alive _x} count crew _v) - 1;
				{
					if (alive _x) then {
						_na = name _x;
						if !(['error',_na] call BIS_fnc_inString) then {
							_t = if!(_crewIndex isEqualTo _crewCount)then[{_t + _na + ', '},{_t + _na}];
						};
						_crewIndex = _crewIndex + 1;
					};
				} count crew _v;
				//if !(_t isEqualTo '') then {_t = format ['(%1)',_t]};
			},{
				if (!isNull driver _v) then [{
					_t = if(QS_crew_Mode == 0)then[{if(_ms < .60)then[{if(_ms > .05) then[{format ['%1 [%2] +%3',_vn,_vt,_n]},{format ['+%1',_n]}]},{format ['+%1',_n]}]},{if(QS_crew_Mode == 1)exitWith{format ['+%1',_n]};if(QS_crew_Mode == 3)exitWith{format ['%1 [%2] +%3',_vn,_vt,_n]}}];
				},{
					_t = if(QS_crew_Mode == 0)then[{if(_ms < .60)then[{if(_ms > .05)then[{format ['[%1] %2 +%3',_vt,_vn,_n]},{format ['+%1',_n]}]},{format ['+%1',_n]}]},{if(QS_crew_Mode == 1)exitWith{format ['+%1',_n]};if(QS_crew_Mode == 3)exitWith{format ['[%1] %2 +%3',_vt,_vn,_n]}}];
				}];
			}];
		},{
			if (!isNull driver _v) then [{
				_t = if(QS_de_MapScale)then[{format ['%1 [%2]',_vn,_vt]},{if(_ms < .60)then[{if(_ms > .05)then[{format ['%1 [%2]',_vn,_vt]},{if(_ms < .006)then[{format ['%1 [%2]',_vn,_vt]},{''}]}]},{''}]}];
			},{
				_t = if(QS_de_MapScale)then[{format ['[%1] %2',_vt,_vn]},{if(_ms < .60)then[{if(_ms > .05)then[{format ['[%1] %2',_vt,_vn]},{if(_ms < .006)then[{format ['[%1] %2',_vt,_vn]},{''}]}]},{''}]}];
			}];
		}];
		if (!isPlayer _v && {unitIsUAV _v}) then {
			if (isUAVConnected _v) then [{
				_y = (UAVControl _v) select 0;
				_yName = if(alive _y)then[{name _y},{"???"}];
				_t = if(QS_de_MapScale)then[{format ['%1 [%2]',_yName,_vt]},{if(_ms < .60)then[{if(_ms > .05)then[{format ['%1 [%2]',_yName,_vt]},{if(_ms < .006)then[{format ['%1 [%2]',_yName,_vt]},{''}]}]},{''}]}];
			},{
				_t = if(QS_de_MapScale)then[{format ['[AUTO] [%1]',_vt]},{if(_ms < .60)then[{if(_ms > .05)then[{format ['[AUTO] [%1]',_vt]},{if(_ms < .006)then[{format ['[AUTO] [%1]',_vt]},{''}]}]},{''}]}];
			}];
		};
	};
	_t;
};

QS_fnc_units_group = {
	private ["_group"];
	_group = units group player - switchableUnits;
	_group + switchableUnits
};

QS_fnc_iconDrawMap = {
	private ["_v","_iconType","_color","_pos","_iconSize","_dir","_text","_shadow","_textSize","_textFont","_textOffset","_units","_side_p","_side_t","_map","_ms"];
	_shadow = 1;
	_textSize = QS_TextSize_MAP;
	_textFont = 'puristaMedium';
	_textOffset = 'right';
	_map = _this select 0;
	_ms = ctrlMapScale _map;
	if (time > missionNamespace getVariable ['QS_updateDraw_map',0]) then {
		missionNamespace setVariable ['QS_updateDraw_map',time + 3];
		//QS_drawArray = (if(isMultiplayer)then[{playableUnits},{call QS_fnc_units_group}]) + allUnitsUav;
		QS_drawArray = (if(isNil "Escape_enemySW_side")then[{playableUnits - Escape_Players_enemy},{Escape_Players_enemy}]) + allUnitsUav; //
	};
	{
		if (!isNull _x) then {
			_v = vehicle _x;
			if (alive _v) then {
				_side_p = if(QS_side_sw)then[{player getVariable ['FAR_unit_Side', side player]},{playerSide}];
				_side_t = if(QS_side_sw)then[{_x getVariable ['FAR_unit_Side', side _x]},{side _x}];
				if (((!isMultiplayer && {_x in switchableUnits}) || {player == _x} || {(_side_t getFriend _side_p >= .6) && {_side_p getFriend _side_t >= .6}}) && {_x == crew _v select 0 || {_x in allUnitsUav}}) then {
					_iconType = [_v] call QS_fnc_iconType;
					_color = [_x,_ms] call QS_fnc_iconColor;
					_pos = getPosASLVisual _v; //在地图上绘图用此命令流畅度较高
					_iconSize = [_v] call QS_fnc_iconSize;	
					_dir = getDirVisual _v; //
					_text = if(QS_isUN_text || {!(_x call QS_fnc_isIncapacitated)})then[{[_v,_ms] call QS_fnc_iconText},{""}];
					if (_v isEqualTo (vehicle player)) then {
						_map drawIcon ['a3\ui_f\data\igui\cfg\islandmap\iconplayer_ca.paa',[1,0,0,.75],_pos,24,24,_dir,'',0,.03,_textFont,_textOffset];
					};
					_map drawIcon [_iconType,_color,_pos,_iconSize,_iconSize,_dir,_text,_shadow,_textSize,_textFont,_textOffset];
				};
			};
		};
	} count QS_drawArray;
	
	if (player isEqualTo (leader group player)) then [{
		if !(groupSelectedUnits player isEqualTo []) then {
			{
				_map drawLine [getPosASLVisual player,getPosASLVisual (vehicle _x),[0,1,1,.5]];
			} count (groupSelectedUnits player);
		};
	},{
		if (isNull objectParent player) then {
			if (isNull objectParent (leader group player)) then {
				if ((leader group player) distance2D player < 300) then {
					_map drawLine [getPosASLVisual player,getPosASLVisual (leader group player),[0,1,1,.5]];
				};
			};
		};
	}];
};

QS_fnc_iconDrawGPS = {
	if (!('MinimapDisplay' in ((infoPanel 'left') + (infoPanel 'right'))) || {visibleMap}) exitWith {};
	private ["_v","_iconType","_color","_pos","_iconSize","_dir","_text","_shadow","_textSize","_textFont","_textOffset","_side_p","_side_t","_gps"];
	_text = "";
	_shadow = 1;
	_textSize = QS_TextSize_GPS;
	_textFont = 'puristaMedium';
	_textOffset = 'right';
	_gps = _this select 0;
	_ms = ctrlMapScale _gps;
	if (time > missionNamespace getVariable ['QS_updateDraw_map',0]) then {
		missionNamespace setVariable ['QS_updateDraw_map',time + 3];
		//QS_drawArray = (if(isMultiplayer)then[{playableUnits},{call QS_fnc_units_group}]) + allUnitsUav;
		QS_drawArray = (if(isNil "Escape_enemySW_side")then[{playableUnits - Escape_Players_enemy},{Escape_Players_enemy}]) + allUnitsUav; //
	};
	{
		if (!isNull _x) then {
			_v = vehicle _x;
			if (alive _v) then {
				_side_p = if(QS_side_sw)then[{player getVariable ['FAR_unit_Side', side player]},{playerSide}];
				_side_t = if(QS_side_sw)then[{_x getVariable ['FAR_unit_Side', side _x]},{side _x}];
				if (((!isMultiplayer && {_x in switchableUnits}) || {player == _x} || {(_side_t getFriend _side_p >= .6) && {_side_p getFriend _side_t >= .6}}) && {_x distance2D player < 300} && {_x == crew _v select 0 || {_x in allUnitsUav}}) then {
					_iconType = [_v] call QS_fnc_iconType;
					_color = [_x] call QS_fnc_iconColor;
					_pos = getPosASLVisual _v;
					_iconSize = [_v] call QS_fnc_iconSize;
					_dir = getDirVisual _x;
					_text = if(QS_showText_GPS && {QS_isUN_text || {!(_x call QS_fnc_isIncapacitated)}})then[{[_v,_ms] call QS_fnc_iconText},{""}];
					_gps drawIcon [_iconType,_color,_pos,_iconSize,_iconSize,_dir,_text,_shadow,_textSize,_textFont,_textOffset];
				};
			};
		};
	} count QS_drawArray;
	
	if (player isEqualTo (leader group player)) then [{
		if !(groupSelectedUnits player isEqualTo []) then {
			{
				_gps drawLine [getPosASLVisual player,getPosASLVisual (vehicle _x),[0,1,1,.5]];
			} count (groupSelectedUnits player);
		};
	},{
		if (isNull objectParent player) then {
			if (isNull objectParent (leader group player)) then {
				if ((leader group player) distance2D player < 300) then {
					_gps drawLine [getPosASLVisual player,getPosASLVisual (leader group player),[0,1,1,.5]];
				};
			};
		};
	}];
};
	
	waitUntil {!isNull player};
	player createDiarySubject ["QS_ST_SET","士兵追踪器"];
	player createDiaryRecord ["QS_ST_SET", ["Soldier Tracker", "<br/>图标文本显示方式<br/><execute expression = 'QS_de_MapScale = true; systemChat ""一直显示"";'>一直显示</execute>  <execute expression = 'QS_de_MapScale = false; systemChat ""自动调整"";'>由缩放自动调整（默认）</execute><br/><br/>乘员文本显示方式，载具乘员两个以上才会有效<br/><execute expression = 'QS_crew_Mode = 0; systemChat ""自动切换"";'>自动切换（默认）</execute>  <execute expression = 'QS_crew_Mode = 1; systemChat ""显示人数"";'>显示人数</execute>  <execute expression = 'QS_crew_Mode = 2; systemChat ""显示所有乘员"";'>显示所有乘员</execute>  <execute expression = 'QS_crew_Mode = 3; systemChat ""显示全部"";'>显示全部</execute><br/><br/>GPS显示图标文本<br/><execute expression = 'QS_showText_GPS = true; systemChat ""是"";'>是</execute>  <execute expression = 'QS_showText_GPS = false; systemChat ""否"";'>否（默认）</execute><br/><br/>单位倒下是否显示图标文本<br/><execute expression = 'QS_isUN_text = true; systemChat ""是"";'>是</execute>  <execute expression = 'QS_isUN_text = false; systemChat ""否"";'>否（默认）</execute><br/><br/><execute expression = '0 spawn QS_fnc_iconAddEH; systemChat ""执行"";'>载入存档不显示除错</execute<br/>"]]; /////
	if (isServer || {serverCommandAvailable "#kick"}) then {player createDiaryRecord ["QS_ST_SET", ["设置", "<br/><execute expression = 'QS_side_sw = !QS_side_sw; publicVariable ""QS_side_sw""; _str = if(QS_side_sw)then[{""是""},{""否""}]; systemChat _str;'>用FAR保存的阵营来判断是否敌对</execute>  <execute expression = 'QS_MAPrequireGPSItem = !QS_MAPrequireGPSItem; publicVariable ""QS_MAPrequireGPSItem""; _str = if(QS_MAPrequireGPSItem)then[{""是""},{""否""}]; systemChat _str;'>有GPS才能在地图上显示单位图标</execute><br/>"]]};
	
if (!isNil "CBA_Settings_fnc_init") then {
	[
		"QS_de_MapScale",
		"CHECKBOX",
		["一直显示图标文本", "或者由缩放比例决定"],
		"士兵追踪器（Soldier Tracker）",
		false,
		false,
		{}
	] call CBA_Settings_fnc_init;
	[
		"QS_isUN_text",
		"CHECKBOX",
		["倒下也显示图标文本", "单位倒下后是否还在地图上显示图标文本"],
		"士兵追踪器（Soldier Tracker）",
		false,
		false,
		{}
	] call CBA_Settings_fnc_init;
	[
		"QS_crew_Mode",
		"LIST",
		["乘员文本显示方式", "载具乘员两个以上才会有效"],
		"士兵追踪器（Soldier Tracker）",
		[[0,1,2,3],["自动切换（默认）","显示人数","显示所有乘员","显示全部"],0],
		false,
		{}
	] call CBA_Settings_fnc_init;
	[
		"QS_TextSize_MAP",
		"SLIDER",
		["地图文本字体大小", ""],
		"士兵追踪器（Soldier Tracker）",
		[.03,.1,.05,3],
		false,
		{}
	] call CBA_Settings_fnc_init;
	[
		"QS_TextSize_GPS",
		"SLIDER",
		["GPS文本字体大小", ""],
		"士兵追踪器（Soldier Tracker）",
		[.03,.1,.05,3],
		false,
		{}
	] call CBA_Settings_fnc_init;
	[
		"QS_showText_GPS",
		"CHECKBOX",
		["GPS显示图标文本", ""],
		"士兵追踪器（Soldier Tracker）",
		false,
		false,
		{}
	] call CBA_Settings_fnc_init;
}; //

QS_fnc_iconAddEH = {
	if (!isNil "QS_once_icons") exitWith {};
	QS_once_icons = 1;
	QS_sw_icons = false;
	sleep 1;
	QS_sw_icons = true;
	if(!isNil "clientEhDrawMap")then{((findDisplay 12) displayCtrl 51) ctrlRemoveEventHandler ["Draw", clientEhDrawMap]; clientEhDrawMap = nil};
	if(!isNil "clientEhDrawGps")then{(QS_gps_control select 0) ctrlRemoveEventHandler ["Draw", clientEhDrawGps]; clientEhDrawGps = nil};
	waitUntil {sleep .1; !isNull(findDisplay 12) || {!QS_sw_icons}};
	QS_once_icons = nil;
	if (QS_sw_icons) then {
		clientEhDrawMap = ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["Draw",{if (!QS_MAPrequireGPSItem || {'ItemGPS' in assignedItems player} || {{["uav",_x] call BIS_fnc_inString} count assignedItems player > 0}) then {_this call QS_fnc_iconDrawMap}}]; //map
		0 spawn {
			scriptName 'Soldier Tracker by Quiksilver - 火炮计算机和无人机控制器界面';
			private ['_QS_display1Opened','_QS_display2Opened'];
			_QS_display1Opened = false;
			_QS_display2Opened = false;
			disableSerialization;
			for '_i' from 0 to 1 step 0 do {
				if (!_QS_display1Opened) then [{
					if (!isNull ((findDisplay 160) displayCtrl 51)) then {
						_QS_display1Opened = true;
						((findDisplay 160) displayCtrl 51) ctrlAddEventHandler ['Draw',QS_fnc_iconDrawMap];
					}; //迫击炮电脑
				},{
					if (isNull ((findDisplay 160) displayCtrl 51)) then {_QS_display1Opened = false};		
				}];
				if (!_QS_display2Opened) then [{
					if (!isNull ((findDisplay -1) displayCtrl 500)) then {
						_QS_display2Opened = true;
						((findDisplay -1) displayCtrl 500) ctrlAddEventHandler ['Draw',QS_fnc_iconDrawMap];
					}; //无人机控制器界面
				},{
					if (isNull ((findDisplay -1) displayCtrl 500)) then {_QS_display2Opened = false};		
				}];
				uiSleep .25;
				if (!QS_sw_icons) exitWith {};
			}; //一直循环
		};
		disableSerialization;
		QS_gps_control = [controlNull]; //禁用序列化时全局(任务命名空间)变量要加[]或者使用局部变量
		private _exit = false;
		for '_x' from 0 to 1 step 0 do {
			{
				if (['311',str _x,false] call BIS_fnc_inString) then {
					if (!isNull (_x displayCtrl 101)) exitWith {
						QS_gps_control = [_x displayCtrl 101];
						_exit = true;
					};
				};
			} forEach (uiNamespace getVariable 'IGUI_displays');
			uiSleep .25;
			if (_exit) exitWith {};
		}; //INIT GPS (等待GPS打开)
		(QS_gps_control select 0) ctrlRemoveAllEventHandlers 'Draw';
		if(QS_sw_icons)then{clientEhDrawGps = (QS_gps_control select 0) ctrlAddEventHandler ["Draw",{_this call QS_fnc_iconDrawGPS}]};
	}; //初始化
}; ////

call QS_fnc_iconAddEH; //


